﻿Public Class LvlStations

    '测站集合
    Public LevelStations As List(Of LvlStation)
    Private mCurrentStationIndex As Integer


    ''' <summary>
    ''' 测站数
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    ReadOnly Property StationCount() As Integer
        Get
            Return LevelStations.Count
        End Get
    End Property

    ''' <summary>
    '''  初始化内存变量
    ''' </summary>
    ''' <remarks></remarks>
    Sub New()
        LevelStations = New List(Of LvlStation)
        LevelStations.Add(New LvlStation)
        mCurrentStationIndex = 0
    End Sub

    ''' <summary>
    ''' 增加新空测站
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function AddNew() As LvlStation
        Dim vStn As LvlStation = LastStation()
        If vStn.BackPoint.ValidPoint Then
            '新增测站
            LevelStations.Add(New LvlStation)
        Else
            '新测站，直接返回
        End If
        mCurrentStationIndex = LevelStations.Count - 1
        Return LevelStations(mCurrentStationIndex)
    End Function

    ''' <summary>
    ''' 获取或设置当前测站
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property CurrentStation() As LvlStation
        Get
            If mCurrentStationIndex < LevelStations.Count - 1 Then
            Else
                mCurrentStationIndex = LevelStations.Count - 1
            End If
            Return LevelStations.Item(mCurrentStationIndex)
        End Get
        Set(ByVal value As LvlStation)
            LevelStations(mCurrentStationIndex) = value
        End Set
    End Property

    ''' <summary>
    ''' 下一站
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function NextStation() As LvlStation
        If mCurrentStationIndex < LevelStations.Count - 1 Then
            mCurrentStationIndex += 1
        Else
            If LevelStations(LevelStations.Count - 1).BackPoint.ValidPoint Then
                LevelStations.Add(New LvlStation)
                mCurrentStationIndex += 1
            End If
        End If
        Return LevelStations(mCurrentStationIndex)
    End Function

    ''' <summary>
    ''' 上一站
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function BeforeStation() As LvlStation
        If mCurrentStationIndex > 0 Then mCurrentStationIndex -= 1
        Return LevelStations(mCurrentStationIndex)
    End Function

    ''' <summary>
    ''' 第一站
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function FirstStation() As LvlStation
        mCurrentStationIndex = 0
        Return LevelStations(0)
    End Function

    ''' <summary>
    ''' 最后一站
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function LastStation() As LvlStation
        mCurrentStationIndex = LevelStations.Count - 1
        Return LevelStations(LevelStations.Count - 1)
    End Function

    Function StationIndexView() As String
        Return (mCurrentStationIndex.ToString + 1).ToString & "/" & LevelStations.Count.ToString
    End Function

    ''' <summary>
    ''' 返回测站的文本字符串
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Overrides Function ToString() As String
        LvlSvPoint.LineNumber = 0
        Dim sTmp As New System.Text.StringBuilder


        'If LvlOption.DistanceMustRead Then
        'sL = "                                     等级水准手簿" & vbCrLf & vbCrLf
        'sL &= "仪器:            尺号:                尺常数:            检查:            复核:" & vbCrLf
        'sL &= "观测:            记录:                天  气:            日期:" & vbCrLf & vbCrLf
        ' sL &= "测站号,  点号,  上丝,  下丝, 视距,    时刻1, 读数1,    时刻2, 读数2,     高差,      高程" & vbCrLf
        'Else
        sTmp.Append("            等级水准手簿" & vbCrLf & vbCrLf)
        sTmp.Append("仪器:" & MyShared.CurrentOpt.InstrNo)
        sTmp.Append("  尺号:" & MyShared.CurrentOpt.Staff1 & "+" & MyShared.CurrentOpt.Staff2)
        sTmp.Append("  尺常数:" & MyShared.ProjectOpt.JiFuCha / MyShared.ProjectOpt.MidReadUnit)
        sTmp.Append("    天气:" & MyShared.CurrentOpt.Weather)
        sTmp.Append("  日期:" & Now.ToString("yy-MM-dd") & vbCrLf & vbCrLf)
   

        ' sL &= "测站号,  点号,    时刻1, 读数1,    时刻2, 读数2,  高差,     高程" & vbCrLf
        'End If

        sTmp.Append(LvlSvPoint.LineHeadWithoutDist)

        For Each Stn As LvlStation In LevelStations
            sTmp.Append(Stn.ToString & vbCrLf)
            sTmp.Append(vbCrLf)
        Next

        sTmp.Append(vbCrLf)
        sTmp.Append("        观测:" & MyShared.CurrentOpt.Surveyor)
        sTmp.Append("          记录:" & MyShared.CurrentOpt.Recordor)
        sTmp.Append("          检查:" & MyShared.CurrentOpt.Examor & vbCrLf)
        Return sTmp.ToString
    End Function
    Function ToStringWithoutDateTime() As String
        LvlSvPoint.LineNumber = 0
        Dim sTmp As String = LvlSvPoint.LineHeadWithoutDateTime
        For Each Stn As LvlStation In LevelStations
            sTmp &= Stn.ForeToStringWithoutDateTime & vbCrLf
            sTmp &= vbCrLf
        Next
        Return sTmp
    End Function

    ''' <summary>
    ''' 用文本初始化水准路线集
    ''' </summary>
    ''' <param name="sData"></param>
    ''' <remarks></remarks>
    ''' 
    Sub Read(ByVal sData As String)
        '初始化数据对象
        LevelStations.Clear()
        LevelStations.Add(New LvlStation)
        mCurrentStationIndex = 0

        '有点号属性（Rb\Rf\Rz）出现的最小行号为起始行,没找到（-1）则不比较
        Dim posRb As Integer = sData.IndexOf("Rb")
        Dim posRf As Integer = sData.IndexOf("Rf")
        Dim posRz As Integer = sData.IndexOf("Rz")
        If posRb < 0 Then Return '没有后视点，数据无用，不读取
        Dim pos As Integer = posRb
        If posRf > -1 Then pos = Math.Min(posRb, posRf)
        If posRz > -1 Then pos = Math.Min(pos, posRz)
        Dim StartPos As Long = Index_of_Start(sData, pos)

        '有点号属性（Rb\Rf\Rz）出现的最大行号为终止行
        pos = Math.Max(sData.LastIndexOf("Rb"), sData.LastIndexOf("Rf"))
        pos = Math.Max(pos, sData.LastIndexOf("Rz"))
        Dim EndPos As Long = Index_of_End(sData, pos)

        sData = sData.Substring(StartPos, EndPos - StartPos + 1)
        Dim sLines() As String = sData.Split(vbCrLf)


        '记录最后换站的点号，用于判断是换站还是换水准路线
        Dim BeforeIsBlankLine As Boolean = False

        For Each sLine As String In sLines
            If sLine.Trim.Length = 0 Then
                If BeforeIsBlankLine Then
                Else
                    BeforeIsBlankLine = True
                    NextStation() '空行为测站换站
                End If

            Else
                BeforeIsBlankLine = False
                If IsReadLine(sLine) Then
                    Dim vP As New LvlSvPoint(sLine)
                    If vP.ValidPoint Then
                        Select Case vP.Prop
                            Case "Rb"
                                CurrentStation.BackPoint = vP

                            Case "Rf"
                                CurrentStation.ForePoint = vP

                            Case "Rz"
                                CurrentStation.MidPoint(vP.Name) = vP
                            Case Else
                        End Select
                    End If

                End If
            End If
        Next
    End Sub
    '已知行内任一位置后求该行起点
    Private Function Index_of_Start(ByRef sData As String, ByVal pos As Long) As Integer
        Do
            Dim tStr As String = sData.Substring(pos, 1)
            If Asc(tStr) = Asc(vbCrLf) Then
                pos += 1
                Exit Do
            Else
                If pos > 0 Then
                    pos -= 1
                Else
                    Exit Do
                End If
            End If
        Loop
        Return pos
    End Function
    '已知行内任一位置后求该行终点
    Private Function Index_of_End(ByRef sData As String, ByVal pos As Long) As Integer
        Dim TotalLength As Long = sData.Length
        Do
            Dim tStr As String = sData.Substring(pos, 1)
            If Asc(tStr) = Asc(vbCrLf) Then
                Exit Do
            Else
                If pos < TotalLength - 1 Then
                    pos += 1
                Else
                    Exit Do
                End If
            End If
        Loop
        Return pos
    End Function
    '有属性行，为观测记录
    Private Function IsReadLine(ByVal sLine As String) As Boolean
        If InStr(sLine, "Rb") > 0 OrElse InStr(sLine, "Rf") > 0 OrElse InStr(sLine, "Rz") > 0 Then
            Return True
        Else
            Return False
        End If
    End Function

    ''' <summary>
    ''' 以文本文件记录水准路线集
    ''' </summary>
    ''' <param name="FileName"></param>
    ''' <remarks></remarks>
    Sub Write(ByVal FileName As String)
        Dim sTmp As String = ToString()
        Try
            If PathAndFile.ExamDictory(FileName) Then

                Dim FN As System.IO.StreamWriter = New IO.StreamWriter(FileName, True)
                FN.WriteLine(sTmp)
                FN.Close()

            End If
        Catch ex As Exception

        End Try
    End Sub


    ''' <summary>
    ''' 返回点号集
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function PointNames() As String
        Dim sTmp As String = String.Empty
        For Each vStn As LvlStation In LevelStations
            Dim ss As String = String.Empty
            ss = vStn.BackPoint.Name : If ss.Length > 0 Then sTmp &= ss & vbCrLf
            ss = vStn.ForePoint.Name : If ss.Length > 0 Then sTmp &= ss & vbCrLf
            For I As Integer = 0 To vStn.MidPointCount - 1
                ss = vStn.MidPoint(I).Name
                If ss.Length > 0 Then sTmp &= ss & vbCrLf
            Next
        Next
        Return sTmp
    End Function

    ''' <summary>
    ''' 配置对比数据
    ''' </summary>
    ''' <remarks></remarks>
    Sub SetCompare(ByRef Compare As LvlCompare)
        For Each stn As LvlStation In LevelStations
            Dim vCmp As New LvlPoint
            If ChangeToComparePnt(stn.BackPoint, vCmp) Then Compare.Add(vCmp)
            If ChangeToComparePnt(stn.ForePoint, vCmp) Then Compare.Add(vCmp)
            For I As Integer = 0 To stn.MidPointCount - 1
                If ChangeToComparePnt(stn.MidPoint(I), vCmp) Then Compare.Add(vCmp)
            Next
        Next
    End Sub
    Private Function ChangeToComparePnt(ByRef vP As LvlSvPoint, ByRef vCmp As LvlPoint) As Boolean
        With vP
            If .ValidPoint Then
                vCmp.Name = .Name
                vCmp.Level = CDbl(.Level)
                Return True
            End If
        End With
        Return False
    End Function

    ''' <summary>
    ''' 测站计算
    ''' </summary>
    ''' <param name="StartPointHeight"></param>
    ''' <remarks></remarks>
    Sub Calculate(ByVal StartPointHeight As Double)
        For i As Integer = 0 To LevelStations.Count - 1
            Dim vStn As LvlStation = LevelStations.Item(i)
            vStn.Calculate(0)
        Next
    End Sub

    '''' <summary>
    ''''点号拷贝 
    '''' </summary>
    '''' <param name="Stns"></param>
    '''' <remarks></remarks>
    'Sub PointNameCopyFrom(ByRef Stns As LvlStations)
    '    For Each Stn As LvlStation In Stns.LevelStations
    '        Dim mStn As New LvlStation
    '        mStn.BackPoint.Name = Stn.BackPoint.Name
    '        mStn.ForePoint.Name = Stn.ForePoint.Name

    '        For I As Integer = 0 To Stn.MidPointCount - 1
    '            Dim vP As New LvlPoint
    '            vP.Name = Stn.MidPoint(I).Name
    '            vP.Prop = "Rz"
    '            mStn.AddMidPoint(vP)
    '        Next

    '        With Me.LevelStations(Me.LevelStations.Count - 1)
    '            If .BackPoint.Name.Length > 0 Then
    '                Me.LevelStations.Add(mStn)
    '            Else
    '                Me.LevelStations(Me.LevelStations.Count - 1) = mStn
    '            End If
    '        End With

    '    Next
    '    mCurrentStationIndex = 0
    'End Sub


End Class
